<% component = metadata.transforms.log_to_metric %>

<%= component_header(component) %>

## Config File

<%= component_config_example(component) %>

## Options

<%= options_table(component.options.to_h.values.sort) %>

## Examples

{% tabs %}
{% tab title="Timings" %}
This example demonstrates capturing timings in your logs.

{% code-tabs %}
{% code-tabs-item title="log" %}
```json
{
  "host": "10.22.11.222",
  "message": "Sent 200 in 54.2ms",
  "status": 200,
  "time": 54.2,
}
```
{% endcode-tabs-item %}
{% endcode-tabs %}

You can convert the `time` field into a `histogram` metric:

{% code-tabs %}
{% code-tabs-item title="vector.toml" %}
```toml
[transforms.log_to_metric]
  type = "log_to_metric"
  
  [[transforms.log_to_metric.metrics]]
    type = "histogram"
    field = "time"
    name = "time_ms" # optional
    tags.status = "{{status}}" # optional
    tags.host = "{{host}}" # optional
```
{% endcode-tabs-item %}
{% endcode-tabs %}

A [`metric` event][docs.metric_event] will be emitted with the following
structure:

```javascript
{
  "histogram": {
    "name": "time_ms",
    "val": 52.2,
    "smaple_rate": 1,
    "tags": {
      "status": "200",
      "host": "10.22.11.222"
    }
  }
}
```

This metric will then proceed down the pipeline, and depending on the sink,
will be aggregated in Vector (such is the case for the [`prometheus` \
sink][docs.prometheus_sink]) or will be aggregated in the store itself.

{% endtab %}
{% tab title="Counting" %}
This example demonstrates counting HTTP status codes.

Given the following log line:

{% code-tabs %}
{% code-tabs-item title="log" %}
```json
{
  "host": "10.22.11.222",
  "message": "Sent 200 in 54.2ms",
  "status": 200
}
```
{% endcode-tabs-item %}
{% endcode-tabs %}

You can count the number of responses by status code:

{% code-tabs %}
{% code-tabs-item title="vector.toml" %}
```toml
[transforms.log_to_metric]
  type = "log_to_metric"
  
  [[transforms.log_to_metric.metrics]]
    type = "counter"
    field = "status"
    name = "response_total" # optional
    tags.status = "{{status}}"
    tags.host = "{{host}}"
```
{% endcode-tabs-item %}
{% endcode-tabs %}

A [`metric` event][docs.metric_event] will be emitted with the following
structure:

```javascript
{
  "counter": {
    "name": "response_total",
    "val": 1.0,
    "tags": {
      "status": "200",
      "host": "10.22.11.222"
    }
  }
}
```

This metric will then proceed down the pipeline, and depending on the sink,
will be aggregated in Vector (such is the case for the [`prometheus` \
sink][docs.prometheus_sink]) or will be aggregated in the store itself.
{% endtab %}
{% tab title="Summing" %}
In this example we'll demonstrate computing a sum. The scenario we've chosen
is to compute the total of orders placed.

Given the following log line:

{% code-tabs %}
{% code-tabs-item title="log" %}
```json
{
  "host": "10.22.11.222",
  "message": "Order placed for $122.20",
  "total": 122.2
}
```
{% endcode-tabs-item %}
{% endcode-tabs %}

You can reduce this log into a `counter` metric that increases by the
field's value:

{% code-tabs %}
{% code-tabs-item title="vector.toml" %}
```toml
[transforms.log_to_metric]
  type = "log_to_metric"
  
  [[transforms.log_to_metric.metrics]]
    type = "counter"
    field = "total"
    name = "order_total" # optional
    increment_by_value = true # optional
    tags.host = "{{host}}" # optional
```
{% endcode-tabs-item %}
{% endcode-tabs %}

A [`metric` event][docs.metric_event] will be emitted with the following
structure:

```javascript
{
  "counter": {
    "name": "order_total",
    "val": 122.20,
    "tags": {
      "host": "10.22.11.222"
    }
  }
}
```

This metric will then proceed down the pipeline, and depending on the sink,
will be aggregated in Vector (such is the case for the [`prometheus` \
sink][docs.prometheus_sink]) or will be aggregated in the store itself.
{% endtab %}
{% tab title="Gauges" %}
In this example we'll demonstrate creating a gauge that represents the current
CPU load verages.

Given the following log line:

{% code-tabs %}
{% code-tabs-item title="log" %}
```json
{
  "host": "10.22.11.222",
  "message": "CPU activity sample",
  "1m_load_avg": 78.2,
  "5m_load_avg": 56.2,
  "15m_load_avg": 48.7
}
```
{% endcode-tabs-item %}
{% endcode-tabs %}

You can reduce this logs into multiple `gauge` metrics:

{% code-tabs %}
{% code-tabs-item title="vector.toml" %}
```toml
[transforms.log_to_metric]
  type = "log_to_metric"
  
  [[transforms.log_to_metric.metrics]]
    type = "gauge"
    field = "1m_load_avg"
    tags.host = "{{host}}" # optional

  [[transforms.log_to_metric.metrics]]
    type = "gauge"
    field = "5m_load_avg"
    tags.host = "{{host}}" # optional

  [[transforms.log_to_metric.metrics]]
    type = "gauge"
    field = "15m_load_avg"
    tags.host = "{{host}}" # optional
```
{% endcode-tabs-item %}
{% endcode-tabs %}

Multiple [`metric` events][docs.metric_event] will be emitted with the following
structure:

```javascript
[
  {
    "gauge": {
      "name": "1m_load_avg",
      "val": 78.2,
      "tags": {
        "host": "10.22.11.222"
      }
    }
  },
  {
    "gauge": {
      "name": "5m_load_avg",
      "val": 56.2,
      "tags": {
        "host": "10.22.11.222"
      }
    }
  },
  {
    "gauge": {
      "name": "15m_load_avg",
      "val": 48.7,
      "tags": {
        "host": "10.22.11.222"
      }
    }
  }
]
```

This metric will then proceed down the pipeline, and depending on the sink,
will be aggregated in Vector (such is the case for the [`prometheus` \
sink][docs.prometheus_sink]) or will be aggregated in the store itself.
{% endtab %}
{% tab title="Sets" %}
In this example we'll demonstrate how to use sets. Sets are primarly a Statsd
concept that represent the number of unique values seens for a given metric.
The idea is that you pass the unique/high-cardinality value as the metric value
and the metric store will count the number of unique values seen.

For example, given the following log line:

{% code-tabs %}
{% code-tabs-item title="log" %}
```json
{
  "host": "10.22.11.222",
  "message": "Sent 200 in 54.2ms",
  "remote_addr": "233.221.232.22"
}
```
{% endcode-tabs-item %}
{% endcode-tabs %}

You can count the number of unique `remote_addr` values by using a set:

{% code-tabs %}
{% code-tabs-item title="vector.toml" %}
```toml
[transforms.log_to_metric]
  type = "log_to_metric"
  
  [[transforms.log_to_metric.metrics]]
    type = "set"
    field = "remote_addr"
    tags.host = "{{host}}" # optional
```
{% endcode-tabs-item %}
{% endcode-tabs %}

A [`metric` event][docs.metric_event] will be emitted with the following
structure:

```javascript
{
  "set": {
    "name": "remote_addr",
    "val": "233.221.232.22",
    "tags": {
      "host": "10.22.11.222"
    }
  }
}
```

This metric will then proceed down the pipeline, and depending on the sink,
will be aggregated in Vector (such is the case for the [`prometheus` \
sink][docs.prometheus_sink]) or will be aggregated in the store itself.
{% endtab %}
{% endtabs %}

## How It Works [[sort]]

<%= component_sections(component) %>

### Multiple Metrics

For clarification, when you convert a single `log` event into multiple `metric`
events, the `metric` events are not emitted as a single array. They are emitted
individually, and the downstream components treat them as individual events.
Downstream components are not aware they were derived from a single log event.

### Null Fields

If the target log `field` contains a `null` value it will ignored, and a metric
will not be emitted.

### Reducing

It's important to understand that this transform does not reduce multiple logs
into a single metric. Instead, this transform converts logs into granular
individual metrics that can then be reduced at the edge. Where the reduction
happens depends on your metrics storage. For example, the
[`prometheus` sink][docs.prometheus_sink] will reduce logs in the sink itself
for the next scrape, while other metrics sinks will proceed to forward the
individual metrics for reduction in the metrics storage itself.

## Troubleshooting

<%= component_troubleshooting(component) %>

## Resources

<%= component_resources(component) %>